#!/usr/bin/env python
# -*- encoding: utf-8 -*-
'''
@File    :   App_WriteDataById_0x2E_test.py
@Time    :   2022/9/13 13:31:28
@Author  :   YangLiang
@Version :   1.0
@Contact :   yangliang@chengtech.com
@License :   (C)Copyright 2022-2025
@Desc    :   None
'''

# here put the import lib
from commDriver.modbus_plc import *
from gettext import find
from xmlrpc.client import Fault
from pytest_assume.plugin import assume
import pytest
import logging
import time
import requests
import binascii
import numpy as np
from commDriver.TS_CAN import *
import allure
import sys
from collections.abc import Iterable
from sqlalchemy import false
import Set_up

sys.dont_write_bytecode = True

# 提取重复代码到单独的函数
def check_dtc_response(Driver, iStep = 1, address = 'UDS'):
    iStep, uds_resp, size = Driver['CAN'].checkReqResp(Driver, '19 0A', '59 0A', 0, iStep, False, address, 'noClearFault')
    respstr = binascii.b2a_hex(bytearray(uds_resp), ' ')
    with allure.step(f"Step{iStep} Response:{respstr}"):
        with assume:
            assert uds_resp[0:3] == [0x59, 0x0A, 0xFF]

        Totle_DTC_List = list(Set_up.DTC_list2.values())
        for real_response in np.array(uds_resp[3:]).reshape(-1, 4):
            current_DTC = real_response[0:3].tolist()
            if current_DTC in Totle_DTC_List:
                Totle_DTC_List.remove(current_DTC)
                logging.info(f'DTC number had found OK, The DTC is: {binascii.b2a_hex(bytearray(current_DTC), " ")}')
                with assume: assert True
            else:
                logging.info(f'DTC number had not found, The DTC is: {binascii.b2a_hex(bytearray(current_DTC), " ")}')
                with assume: assert False
        if Totle_DTC_List:
            for a in Totle_DTC_List:
                logging.info(f'DTC Number ------ {binascii.b2a_hex(bytearray(a), " ")} not include')
            with assume: assert False
        else:
            logging.info('All DTC number had been match')
            with assume: assert True
        iStep + 1
    # 暂停107信号，生成故障
    iStep = Driver['CAN'].SetLostCommunicationStatus(Driver, iStep, False)
    time.sleep(1)
    iStep, uds_resp, size = Driver['CAN'].checkReqResp(Driver, '19 0A', '59 0A', 0, iStep, False, address, 'noClearFault')
    isTrue = is_sub_array_with_slicing([0xD0,0x97,0x87,0x2F], uds_resp)
    with assume: assert True == isTrue
    # 恢复107信号，故障消失
    iStep = Driver['CAN'].SetLostCommunicationStatus(Driver, iStep, True)
    time.sleep(1)
    iStep, uds_resp, size = Driver['CAN'].checkReqResp(Driver, '19 0A', '59 0A', 0, iStep, False, address, 'noClearFault')
    isTrue = is_sub_array_with_slicing([0xD0,0x97,0x87,0x2E], uds_resp)
    with assume: assert True == isTrue
    iStep, uds_resp, size = Driver['CAN'].checkReqResp(Driver, '14 FF FF FF', '54', 0, iStep, False, address, 'noClearFault')

    return iStep

def is_sub_array_with_slicing(small_array, large_array, iStep = 1):
    with allure.step(f"Step{iStep} check {small_array} in {large_array} # "):
        small_len = len(small_array)
        large_len = len(large_array)
        for i in range(large_len - small_len + 1):
            if large_array[i:i + small_len] == small_array:
                return True
    return False
        
        

class Test_ReportSupportedDTC_phy(object):
    # 物理寻址，默认模式，读取支持的DTC
    @allure.severity('normal')
    @allure.title("Test ReportSupportedDTC by SID 0x19 in default session with physical addressing")
    def test_ReportSupportedDTC_Default_Phy(self, action, Driver):
        time.sleep(1.5)
        iStep = 1
        iStep, uds_resp, size = Driver['CAN'].checkReqResp(Driver, '10 01', '50 01', 0, iStep, False, 'UDS', 'ClearFault')
        iStep = check_dtc_response(Driver,iStep)
        


    # 物理寻址，默认模式，读取支持的DTC
    @allure.severity('normal')
    @allure.title("Test ReportSupportedDTC by SID 0x19 in default session with physical addressing")
    def test_ReportSupportedDTC_Extended_Phy(self, action, Driver):
        time.sleep(1.5)
        iStep = 1
        iStep, uds_resp, size = Driver['CAN'].checkReqResp(Driver, '10 03', '50 03', 0, iStep, False, 'UDS', 'ClearFault')
        iStep = check_dtc_response(Driver,iStep)

class Test_ReportSupportedDTC_Fun(object):
    # 物理寻址，默认模式，读取支持的DTC
    @allure.severity('normal')
    @allure.title("Test ReportSupportedDTC by SID 0x19 in default session with functional addressing")
    def test_ReportSupportedDTC_Default_Fun(self, action, Driver):
        time.sleep(1.5)
        iStep = 1
        iStep, uds_resp, size = Driver['CAN'].checkReqResp(Driver, '10 01', '50 01', 0, iStep, False, 'UDSFun', 'ClearFault')
        iStep = check_dtc_response(Driver,iStep, 'UDSFun')
        


    # 物理寻址，默认模式，读取支持的DTC
    @allure.severity('normal')
    @allure.title("Test ReportSupportedDTC by SID 0x19 in default session with functional addressing")
    def test_ReportSupportedDTC_Extended_Fun(self, action, Driver):
        time.sleep(1.5)
        iStep = 1
        iStep, uds_resp, size = Driver['CAN'].checkReqResp(Driver, '10 03', '50 03', 0, iStep, False, 'UDSFun', 'ClearFault')
        iStep = check_dtc_response(Driver,iStep, 'UDSFun')